'''
Description: 
Author: Zilu
Date: 2021-11-10 19:24:13
Version: 
LastEditTime: 2021-11-10 21:19:10
LastEditors: Zilu
'''

# 正则表达式可以用字符来描述匹配规则
# \d 匹配一个数字，\w 匹配一个字母或者数字
# '00\d' 可以匹配 '007'、'009' 但不能匹配 '00A'
# '\d\d\d' 可以匹配 '011'
# '\w\w\d' 可以匹配 'py3'

# \s可以匹配一个空格（也包括Tab等空白符）
# \s+ 表示至少有一个空格，例如匹配' '、' '等

# . 可以匹配任何字符 
# 'py.' 可以匹配 'pyc'、'pyo'、'py!'等等

# *（任意个，包括0）、+（至少1个）、?（0个或1个）、{n,m}（n-m个字符）可以匹配边长的字符串

# 可以用 [] 表示匹配范围
# [0-9a-zA-Z\_] 可以匹配1个数字、字母或者下划线
# [0-9a-zA-Z\_]+ 可以匹配至少由1个数字、字母或者下划线组成的字符串，如 'a100'、'0Z_'、'py200'等

# A|B 表示匹配 A 或 B 
# (P|p)ython可以匹配'Python'或者'python'

# ^ 表示行的开头，^\d 表示必须以数字开头
# $ 表示行的结束，\d$ 表示必须以数字结束

# python 中使用 re 模块表示正则表达式
# 尽量在字符串前使用 r前缀，因为python本身也使用\转义
import re
re.match(r'^\d{3}\-\d{3,8}$','010-12345')
re.match(r'^\d{3}\-\d{3,8}$','010 - 12345')

# match 方法成功则返回一个 Match 对象，否则返回None

# 切分字符串
'a b    c'.split()
'a b    c'.split(' ')
re.split(r'\s+','a b    c')
re.split(r'[\s\,]+','a,b,   c,   d')

# 正则表达式可以用 () 提取分组
m = re.match(r'^(\d{3})\-(\d{3,8})$','010-12345')
m[0]
m[1]
m[2]

# 识别时间
t = '19:58:20'
m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])', t)
m[0]
m[1]
m[2]

# 正则匹配时贪婪匹配，尽量匹配多个字符
re.match(r'^(\d+)(0*)$','10230000').groups()
# 可以添加一个 ? 采用非贪婪匹配
re.match(r'^(\d+?)(0*)$','10230000').groups()

# 练习：请尝试写一个验证Email地址的正则表达式。版本一应该可以验证出类似的Email：
# someone@gmail.com
# bill.gates@microsoft.com
def is_valid_email(addr):
    if re.match(r'\b[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,6}\b', addr):
        return True
    else:
        return False

# 版本二可以提取出带名字的Email地址：
# <Tom Paris> tom@voyager.org => Tom Paris
# bob@example.com => bob
def name_of_email(addr):
    m = re.match(r'(<?([\w\s]+)>?\s?[\w]+)@[\w.-]+\.[a-zA-Z]{2,6}', addr)
    if m[1].find('>') != -1 or m[1].find('>') != -1:
        return m[2]
    else:
        return m[1]

e1 = '<Tom Paris> tom@voyager.org'
e2 = 'tom@example.com'
f = name_of_email(e2)
f